import React, { useEffect, useRef, useState } from 'react';
import * as THREE from 'three';
import Blockly from 'blockly';
import { registerCustomBlocks } from './utils/blocks';
import './App.css';

function App() {
  const blocklyDiv = useRef<HTMLDivElement>(null);
  const threeContainer = useRef<HTMLDivElement>(null);
  const [scene, setScene] = useState<THREE.Scene | null>(null);
  const [renderer, setRenderer] = useState<THREE.WebGLRenderer | null>(null);
  const [camera, setCamera] = useState<THREE.PerspectiveCamera | null>(null);
  const [workspace, setWorkspace] = useState<Blockly.WorkspaceSvg | null>(null);

  // 初始化Three.js场景
  const initThreeScene = () => {
    if (!threeContainer.current) return;

    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    const renderer = new THREE.WebGLRenderer();
    
    renderer.setSize(threeContainer.current.clientWidth, threeContainer.current.clientHeight);
    threeContainer.current.appendChild(renderer.domElement);
    camera.position.z = 5;

    setScene(scene);
    setRenderer(renderer);
    setCamera(camera);

    return { scene, renderer, camera };
  };

  // 3D对象创建函数
  const [objects, setObjects] = useState<THREE.Mesh[]>([]);

  const create3DObject = (type: string, params: any) => {
    if (!scene) return null;

    let object: THREE.Mesh;
    switch(type) {
      case 'cube':
        const size = params.size || 1;
        const geometry = new THREE.BoxGeometry(size, size, size);
        const material = new THREE.MeshBasicMaterial({ color: params.color || 0x00ff00 });
        object = new THREE.Mesh(geometry, material);
        break;
      case 'sphere':
        const radius = params.radius || 1;
        const sphereGeometry = new THREE.SphereGeometry(radius);
        const sphereMaterial = new THREE.MeshBasicMaterial({ color: params.color || 0xff0000 });
        object = new THREE.Mesh(sphereGeometry, sphereMaterial);
        break;
      case 'cylinder':
        const cylRadius = params.radius || 1;
        const height = params.height || 2;
        const cylGeometry = new THREE.CylinderGeometry(cylRadius, cylRadius, height);
        const cylMaterial = new THREE.MeshBasicMaterial({ color: params.color || 0x0000ff });
        object = new THREE.Mesh(cylGeometry, cylMaterial);
        break;
      default:
        return null;
    }

    scene.add(object);
    setObjects(prev => [...prev, object]);
    return object;
  };

  const moveObject = (index: number, x: number, y: number, z: number) => {
    if (index >= 0 && index < objects.length) {
      objects[index].position.set(x, y, z);
    }
  };

  const rotateObject = (index: number, axis: string, angle: number) => {
    if (index >= 0 && index < objects.length) {
      const radians = THREE.MathUtils.degToRad(angle);
      switch(axis) {
        case 'x':
          objects[index].rotation.x = radians;
          break;
        case 'y':
          objects[index].rotation.y = radians;
          break;
        case 'z':
          objects[index].rotation.z = radians;
          break;
      }
    }
  };

  // 动画循环
  const animate = () => {
    if (!renderer || !scene || !camera) return;

    requestAnimationFrame(animate);
    renderer.render(scene, camera);
  };

  useEffect(() => {
    // 初始化Blockly
    if (blocklyDiv.current) {
      const workspace = Blockly.inject(blocklyDiv.current, {
        toolbox: document.getElementById('toolbox') as Element,
        trashcan: true
      });
      setWorkspace(workspace);
      registerCustomBlocks(workspace);

      // 添加代码生成器
      workspace.addChangeListener((event) => {
        if (event.type === Blockly.Events.BLOCK_CHANGE ||
            event.type === Blockly.Events.BLOCK_CREATE ||
            event.type === Blockly.Events.BLOCK_DELETE) {
          const code = Blockly.JavaScript.workspaceToCode(workspace);
          try {
            // 执行生成的代码
            const executeCode = new Function(
              'create3DObject', 
              'moveObject', 
              'rotateObject',
              'objects',
              'let currentObjectIndex = 0;\n' + code
            );
            executeCode(
              create3DObject,
              moveObject,
              rotateObject,
              objects
            );
          } catch (error) {
            console.error('Error executing generated code:', error);
          }
        }
      });
    }

    // 初始化Three.js
    initThreeScene();
    animate();

    // 窗口大小调整处理
    const handleResize = () => {
      if (camera && renderer && threeContainer.current) {
        camera.aspect = threeContainer.current.clientWidth / threeContainer.current.clientHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(threeContainer.current.clientWidth, threeContainer.current.clientHeight);
      }
    };

    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return (
    <div className="app-container">
      <div className="blockly-container" ref={blocklyDiv}></div>
      <div className="three-container" ref={threeContainer}></div>
    </div>
  );
}

export default App;